package com.wzj.yygh.hosp.mongotest;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.beans.PropertyDescriptor;
import java.util.*;

/**
 * 属性复制(不复制空属性)
 *
 */
public class BeanNotNullUtil {

    /**
     * 获取到对象中属性为null的属性名
     *
     * @param source
     * @return
     */
    private static String[] getNullPropertyNames(Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<>();
        for (PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (ObjectUtils.isEmpty(srcValue)) {
                emptyNames.add(pd.getName());
            }
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

    /**
     * 拷贝非空对象属性值
     *
     * @param source
     * @param target
     */
    public static void copyPropertiesIgnoreNull(Object source, Object target) {
        BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
    }

    /**
     * 集合拷贝非空数据
     *
     * @param source       数据源
     * @param target       目标
     * @param propertyName 要匹配的属性名,例如两个集合使用id进行匹配拷贝 propertyName: "id"
     */
    public static void copyListPropertiesIgnoreNull(List<?> source, List<?> target, String propertyName) {
        if (CollectionUtils.isEmpty(source)) {
            throw new NullPointerException("copyListPropertiesIgnoreNull source源数据为空!");
        }
        Map<Object, Object> map = new HashMap<>(source.size());
        source.forEach(s -> {
            final BeanWrapper sourceBean = new BeanWrapperImpl(s);
            Object value = sourceBean.getPropertyValue(propertyName);
            if (value == null) {
                throw new NullPointerException("copyListPropertiesIgnoreNull获取参数异常");
            }
            map.put(value, s);
        });
        target.forEach(s -> {
            final BeanWrapper targetBean = new BeanWrapperImpl(s);
            Object value = targetBean.getPropertyValue(propertyName);
            if (value == null) {
                throw new NullPointerException("copyListPropertiesIgnoreNull获取参数异常");
            }
            Object o = map.get(value);
            copyPropertiesIgnoreNull(o, s);
        });
    }
}